<template>
  <div @mousemove="handleMove" @click="handleClick" class="container">
    <canvas ref="canvasRef" width="634" height="591"></canvas>
    <div
      style="margin: 0 auto; /* 左右居中 */ top: 25px"
      :style="apuStyle"
      class="apu"
    ></div>
    <div :style="secStyle" class="sec_ext_pwr"></div>
    <div :style="apuColor" style="left: 340px; top: -58px" class="disc_font">
      APU
    </div>
    <div :style="apuColor" style="left: 340px; top: -68px" class="disc_font">
      GEN
    </div>
    <div
      :style="secExtPwrColor"
      style="left: 210px; top: 35px"
      class="disc_font"
    >
      SEC
    </div>
    <div
      :style="secExtPwrColor"
      style="left: 190px; top: 25px"
      class="disc_font"
    >
      EXT&nbsp;PWR
    </div>
    <div :style="extStyle" class="prt_ext_pwr"></div>
    <div
      :style="prtExtPwrColor"
      style="left: 375px; top: -60px"
      class="disc_font"
    >
      PRT
    </div>
    <div
      :style="prtExtPwrColor"
      style="left: 355px; top: -70px"
      class="disc_font"
    >
      EXT&nbsp;PWR
    </div>
    <div :style="lMainBus" style="left: 44px; top: -64px" class="bus">
      L&nbsp;MAIN
    </div>
    <div :style="rMainBus" style="left: 478px; top: -89px" class="bus">
      R&nbsp;MAIN
    </div>
    <div
      style="top: -90px; left: 105px"
      :style="lutilBusStyle"
      class="plainFont"
    >
      L&nbsp;UTIL
    </div>
    <div
      style="top: -97px; left: 90px"
      :style="lutilBusStyle"
      class="plainFont"
    >
      LOAD&nbsp;SHED
    </div>
    <div
      style="top: -138px; left: 480px"
      :style="rutilBusStyle"
      class="plainFont"
    >
      R&nbsp;UTIL
    </div>
    <div
      style="top: -146px; left: 450px"
      :style="rutilBusStyle"
      class="plainFont"
    >
      LOAD&nbsp;SHED
    </div>
    <div
      style="top: -116px; left: 50px"
      :style="genControlStyle1"
      class="apu"
    ></div>
    <div
      style="top: -156px; left: 539px"
      :style="genControlStyle2"
      class="apu"
    ></div>
    <div :style="lXfrStyle" style="left: 184px; top: -213px" class="bus">
      L&nbsp;XFR
    </div>
    <div :style="rXfrStyle" style="left: 335px; top: -238px" class="bus">
      R&nbsp;XFR
    </div>
    <div :style="lGenColor" style="left: 95px; top: -250px" class="disc_font">
      L&nbsp;GEN
    </div>
    <div :style="lGenColor" style="left: 100px; top: -260px" class="disc_font">
      CTRL
    </div>
    <div :style="rGenColor" style="left: 490px; top: -300px" class="disc_font">
      R&nbsp;GEN
    </div>
    <div :style="rGenColor" style="left: 495px; top: -310px" class="disc_font">
      CTRL
    </div>
    <div
      style="top: -274px; left: 195px"
      :style="lBackupStyle"
      class="apu"
    ></div>
    <div
      style="top: -312px; left: 392px"
      :style="rBackupStyle"
      class="apu"
    ></div>
    <div
      :style="lBusTieColor"
      style="left: 130px; top: -630px"
      class="disc_font"
    >
      L&nbsp;BUS&nbsp;TIE
    </div>
    <div
      :style="rBusTieColor"
      style="left: 440px; top: -655px"
      class="disc_font"
    >
      R&nbsp;BUS&nbsp;TIE
    </div>
    <div
      :style="lBackupColor"
      style="left: 212px; top: -360px"
      class="disc_font"
    >
      L
    </div>
    <div
      :style="rBackupColor"
      style="left: 408px; top: -380px"
      class="disc_font"
    >
      R
    </div>
    <div style="left: 285px; top: -450px" class="disc_font">BACKUP</div>
    <div style="left: 300px; top: -460px" class="disc_font">GEN</div>
    <div
      style="left: 46px; top: -510px"
      :style="lDriveStyle"
      class="drive"
    ></div>
    <div
      style="left: 534px; top: -550px"
      :style="rDriveStyle"
      class="drive"
    ></div>
    <div style="left: 44px; top: -545px" class="disc_font">L&nbsp;DRIVE</div>
    <div style="left: 530px; top: -570px" class="disc_font">R&nbsp;DRIVE</div>
    <Lower style="top: -550px" />
  </div>
</template>
<script setup>
import {
  ref,
  onMounted,
  reactive,
  onBeforeUnmount,
  computed,
  watch,
} from "vue";
import { mapGetters, useStore } from "vuex";
import Lower from "./lower.vue";

const store = useStore();
const canvasRef = ref(null);
const PI = Math.PI;

const apuStyle = reactive({
  border: "3px solid rgb(8, 255, 66)",
});

const genControlStyle1 = reactive({
  border: "3px solid rgb(8, 255, 66)",
});

const genControlStyle2 = reactive({
  border: "3px solid rgb(8, 255, 66)",
});

const secStyle = reactive({
  border: "3px solid rgb(255, 255, 255)",
});

const extStyle = reactive({
  border: "3px solid rgb(255, 255, 255)",
});

const lMainBus = reactive({
  border: "3px solid rgb(8, 255, 66)",
  color: "rgb(8, 255, 66)",
});

const rMainBus = reactive({
  border: "3px solid rgb(8, 255, 66)",
  color: "rgb(8, 255, 66)",
});

const lXfrStyle = reactive({
  border: "3px solid rgb(8, 255, 66)",
  color: "rgb(8, 255, 66)",
});

const rXfrStyle = reactive({
  border: "3px solid rgb(8, 255, 66)",
  color: "rgb(8, 255, 66)",
});

const lBackupStyle = reactive({
  border: "3px solid rgb(8, 255, 66)",
});

const rBackupStyle = reactive({
  border: "3px solid rgb(8, 255, 66)",
});

const lDriveStyle = reactive({
  border: "3px solid rgb(8, 255, 66)",
});

const rDriveStyle = reactive({
  border: "3px solid rgb(8, 255, 66)",
});

const lutilBusStyle = reactive({
  color: "white",
});

const rutilBusStyle = reactive({
  color: "white",
});

const apuColor = reactive({
  color: "rgb(8,214,255)",
});

const lBusTieColor = reactive({
  color: "rgb(8,214,255)",
});

const rBusTieColor = reactive({
  color: "rgb(8,214,255)",
});

const secExtPwrColor = reactive({
  color: "rgb(8,214,255)",
});

const prtExtPwrColor = reactive({
  color: "rgb(8,214,255)",
});

const lGenColor = reactive({
  color: "rgb(8,214,255)",
});

const rGenColor = reactive({
  color: "rgb(8,214,255)",
});

const lBackupColor = reactive({
  color: "rgb(8,214,255)",
});

const rBackupColor = reactive({
  color: "rgb(8,214,255)",
});

// 使用 computed 映射 getters
const lBusTie = computed(() => store.getters["elec/lBusTie"]);
const rBusTie = computed(() => store.getters["elec/rBusTie"]);
const utilBus = computed(() => store.getters["elec/utilBus"]);
const lGenCtrl = computed(() => store.getters["elec/lGenCtrl"]);
const rGenCtrl = computed(() => store.getters["elec/rGenCtrl"]);
const ApuGen = computed(() => store.getters["elec/ApuGen"]);
const lBackupGen = computed(() => store.getters["elec/lBackupGen"]);
const rBackupGen = computed(() => store.getters["elec/rBackupGen"]);
const secExtPwr = computed(() => store.getters["elec/secExtPwr"]);
const prtExtPwr = computed(() => store.getters["elec/prtExtPwr"]);

watch(
  [
    () => store.getters["elec/lBusTie"],
    () => store.getters["elec/rBusTie"],
    () => store.getters["elec/utilBus"],
    () => store.getters["elec/lGenCtrl"],
    () => store.getters["elec/rGenCtrl"],
    () => store.getters["elec/ApuGen"],
    () => store.getters["elec/lBackupGen"],
    () => store.getters["elec/rBackupGen"],
    () => store.getters["elec/secExtPwr"],
    () => store.getters["elec/prtExtPwr"],
  ],
  (newVal, oldVal) => {
    // 遍历新旧值
    newVal.forEach((val, index) => {
      const getterNames = [
        "lBusTie",
        "rBusTie",
        "utilBus",
        "lGenCtrl",
        "rGenCtrl",
        "ApuGen",
        "lBackupGen",
        "rBackupGen",
        "secExtPwr",
        "prtExtPwr",
      ];

      const getterName = getterNames[index];
      const oldValForGetter = oldVal[index];
      const newValForGetter = newVal[index];
      if (newValForGetter !== oldValForGetter) {
        // 根据不同的属性调用不同的方法
        switch (getterName) {
          case "lBusTie":
            drawCanvas();
            break;
          case "rBusTie":
            drawCanvas();
            break;
          case "utilBus":
            drawCanvas();
            break;
          case "lGenCtrl":
            if (oldValForGetter && !newValForGetter) {
              // true to false - yellow for 2s then white, with yellow X
              genControlStyle1.border = "3px solid yellow";
              genControlStyle1.background = `linear-gradient(45deg, transparent 47%, yellow 47%, yellow 53%, transparent 53%),
                                           linear-gradient(-45deg, transparent 47%, yellow 47%, yellow 53%, transparent 53%)`;
              setTimeout(() => {
                genControlStyle1.border = "3px solid rgb(255, 255, 255)";
                genControlStyle1.background = "none";
              }, 2000);
            } else if (!oldValForGetter && newValForGetter) {
              // false to true - directly to green
              genControlStyle1.border = "3px solid rgb(8, 255, 66)";
            }
            drawCanvas();
            break;
          case "rGenCtrl":
            if (oldValForGetter && !newValForGetter) {
              // true to false - yellow for 2s then white, with yellow X
              genControlStyle2.border = "3px solid yellow";
              genControlStyle2.background = `linear-gradient(45deg, transparent 47%, yellow 47%, yellow 53%, transparent 53%),
                                           linear-gradient(-45deg, transparent 47%, yellow 47%, yellow 53%, transparent 53%)`;
              setTimeout(() => {
                genControlStyle2.border = "3px solid rgb(255, 255, 255)";
                genControlStyle2.background = "none";
              }, 2000);
            } else if (!oldValForGetter && newValForGetter) {
              // false to true - directly to green
              genControlStyle2.border = "3px solid rgb(8, 255, 66)";
            }
            drawCanvas();
            break;
          case "ApuGen":
            apuStyle.border = newValForGetter
              ? "3px solid rgb(8, 255, 66)"
              : "3px solid rgb(255, 255, 255)";
            drawCanvas();
            break;
          case "lBackupGen":
            lBackupStyle.border = newValForGetter
              ? "3px solid rgb(8, 255, 66)"
              : "3px solid rgb(255, 255, 255)";
            drawCanvas();
            break;
          case "rBackupGen":
            rBackupStyle.border = newValForGetter
              ? "3px solid rgb(8, 255, 66)"
              : "3px solid rgb(255, 255, 255)";
            drawCanvas();
            break;
          case "secExtPwr":
            secStyle.border = newValForGetter
              ? "3px solid rgb(8, 255, 66)"
              : "3px solid rgb(255, 255, 255)";
            drawCanvas();
            break;
          case "prtExtPwr":
            extStyle.border = newValForGetter
              ? "3px solid rgb(8, 255, 66)"
              : "3px solid rgb(255, 255, 255)";
            drawCanvas();
            break;
          default:
            console.log("Unknown property change");
        }
      }
    });
  }
);

const boxes = [
  { x: 295, y: 105, width: 84, height: 40 },
  { x: 127, y: 145, width: 70, height: 44 },
  { x: 450, y: 145, width: 70, height: 44 },
  { x: 187, y: 206, width: 68, height: 70 },
  { x: 353, y: 206, width: 68, height: 70 },
  { x: 80, y: 316, width: 94, height: 28 },
  { x: 445, y: 316, width: 94, height: 28 },
  { x: 48, y: 375, width: 87, height: 40 },
  { x: 487, y: 375, width: 87, height: 40 },
  { x: 191, y: 443, width: 40, height: 60 },
  { x: 391, y: 443, width: 40, height: 60 },
];

const handleMove = (event) => {
  const container = document.querySelector(".simulator_container");
  const rect = container.getBoundingClientRect();
  const x = event.clientX - rect.left;
  const y = event.clientY - rect.top;
  if (
    x >= boxes[0].x &&
    x <= boxes[0].x + boxes[0].width &&
    y >= boxes[0].y &&
    y <= boxes[0].y + boxes[0].height
  ) {
    //设置Apu
    document.body.style.cursor = "pointer";
    // 当鼠标点击时触发相应的方法
    clickItem = "apuColor";
    apuColor.color = "rgb(8,255,66)";
  } else if (
    x >= boxes[1].x &&
    x <= boxes[1].x + boxes[1].width &&
    y >= boxes[1].y &&
    y <= boxes[1].y + boxes[1].height
  ) {
    //设置l bus tie
    document.body.style.cursor = "pointer";
    // 当鼠标点击时触发相应的方法
    clickItem = "lBusTie";
    lBusTieColor.color = "rgb(8,255,66)";
  } else if (
    x >= boxes[2].x &&
    x <= boxes[2].x + boxes[2].width &&
    y >= boxes[2].y &&
    y <= boxes[2].y + boxes[2].height
  ) {
    //设置r bus tie
    document.body.style.cursor = "pointer";
    // 当鼠标点击时触发相应的方法
    clickItem = "rBusTie";
    rBusTieColor.color = "rgb(8,255,66)";
  } else if (
    x >= boxes[3].x &&
    x <= boxes[3].x + boxes[3].width &&
    y >= boxes[3].y &&
    y <= boxes[3].y + boxes[3].height
  ) {
    //设置sec ext pwr
    document.body.style.cursor = "pointer";
    // 当鼠标点击时触发相应的方法
    clickItem = "secExtPwr";
    secExtPwrColor.color = "rgb(8,255,66)";
  } else if (
    x >= boxes[4].x &&
    x <= boxes[4].x + boxes[4].width &&
    y >= boxes[4].y &&
    y <= boxes[4].y + boxes[4].height
  ) {
    //设置prt ext pwr
    document.body.style.cursor = "pointer";
    // 当鼠标点击时触发相应的方法
    clickItem = "prtExtPwr";
    prtExtPwrColor.color = "rgb(8,255,66)";
  } else if (
    (x >= boxes[5].x &&
      x <= boxes[5].x + boxes[5].width &&
      y >= boxes[5].y &&
      y <= boxes[5].y + boxes[5].height) ||
    (x >= boxes[6].x &&
      x <= boxes[6].x + boxes[6].width &&
      y >= boxes[6].y &&
      y <= boxes[6].y + boxes[6].height)
  ) {
    //设置util load shed
    document.body.style.cursor = "pointer";
    // 当鼠标点击时触发相应的方法
    clickItem = "utilBus";
    rutilBusStyle.color = "rgb(8,255,66)";
    lutilBusStyle.color = "rgb(8,255,66)";
  } else if (
    x >= boxes[7].x &&
    x <= boxes[7].x + boxes[7].width &&
    y >= boxes[7].y &&
    y <= boxes[7].y + boxes[7].height
  ) {
    //设置l gen ctrl
    document.body.style.cursor = "pointer";
    // 当鼠标点击时触发相应的方法
    clickItem = "lGenCtrl";
    lGenColor.color = "rgb(8,255,66)";
  } else if (
    x >= boxes[8].x &&
    x <= boxes[8].x + boxes[8].width &&
    y >= boxes[8].y &&
    y <= boxes[8].y + boxes[8].height
  ) {
    //设置r gen ctrl
    document.body.style.cursor = "pointer";
    // 当鼠标点击时触发相应的方法
    clickItem = "rGenCtrl";
    rGenColor.color = "rgb(8,255,66)";
  } else if (
    x >= boxes[9].x &&
    x <= boxes[9].x + boxes[9].width &&
    y >= boxes[9].y &&
    y <= boxes[9].y + boxes[9].height
  ) {
    //设置l backup gen
    document.body.style.cursor = "pointer";
    // 当鼠标点击时触发相应的方法
    clickItem = "lBackupGen";
    lBackupColor.color = "rgb(8,255,66)";
  } else if (
    x >= boxes[10].x &&
    x <= boxes[10].x + boxes[10].width &&
    y >= boxes[10].y &&
    y <= boxes[10].y + boxes[10].height
  ) {
    //设置r backup gen
    document.body.style.cursor = "pointer";
    // 当鼠标点击时触发相应的方法
    clickItem = "rBackupGen";
    rBackupColor.color = "rgb(8,255,66)";
  } else {
    document.body.style.cursor = "default";
    if (clickItem) {
      switch (clickItem) {
        case "apuColor":
          apuColor.color = "rgb(8,214,255)";
          break;
        case "lBusTie":
          lBusTieColor.color = "rgb(8,214,255)";
          break;
        case "rBusTie":
          rBusTieColor.color = "rgb(8,214,255)";
          break;
        case "utilBus":
          lutilBusStyle.color = "rgb(8,214,255)";
          rutilBusStyle.color = "rgb(8,214,255)";
          break;
        case "lGenCtrl":
          lGenColor.color = "rgb(8,214,255)";
          break;
        case "rGenCtrl":
          rGenColor.color = "rgb(8,214,255)";
          break;
        case "ApuGen":
          apuStyle.color = "rgb(8,214,255)";
          break;
        case "lBackupGen":
          lBackupColor.color = "rgb(8,214,255)";
          break;
        case "rBackupGen":
          rBackupColor.color = "rgb(8,214,255)";
          break;
        case "secExtPwr":
          secExtPwrColor.color = "rgb(8,214,255)";
          break;
        case "prtExtPwr":
          prtExtPwrColor.color = "rgb(8,214,255)";
          break;
        default:
          console.log("Unknown clickItem");
      }
    }
    clickItem = null;
  }
};

let clickItem = null;

const handleClick = (event) => {
  if (clickItem) {
    switch (clickItem) {
      case "apuColor":
        //设置elec.js的apu的状态
        store.dispatch("elec/toggleApuGen");
        break;
      case "lBusTie":
        store.dispatch("elec/toggleLBusTie");
        break;
      case "rBusTie":
        store.dispatch("elec/toggleRBusTie");
        break;
      case "utilBus":
        store.dispatch("elec/toggleUtilBus");
        break;
      case "lGenCtrl":
        store.dispatch("elec/toggleLGenCtrl");
        break;
      case "rGenCtrl":
        store.dispatch("elec/toggleRGenCtrl");
        break;
      case "lBackupGen":
        store.dispatch("elec/toggleLBackupGen");
        break;
      case "rBackupGen":
        store.dispatch("elec/toggleRBackupGen");
        break;
      case "secExtPwr":
        store.dispatch("elec/toggleSecExtPwr");
        break;
      case "prtExtPwr":
        store.dispatch("elec/togglePrtExtPwr");
        break;
      default:
        console.log("Unknown clickItem");
    }
  }
};

onMounted(() => {
  drawCanvas();
  window.addEventListener("keydown", handleKeydown); // 在组件挂载时添加键盘事件监听
});

onBeforeUnmount(() => {
  window.removeEventListener("keydown", handleKeydown); // 在组件销毁时移除事件监听
});

const handleKeydown = (event) => {
  // 将按键转换为大写字母
  const key = event.key.toLowerCase();
  const canvas = canvasRef.value;
  if (canvas.getContext) {
    const ctx = canvas.getContext("2d");
    const keyActions = {
      q: () => store.dispatch("elec/toggleLBusTie"),
      w: () => store.dispatch("elec/toggleRBusTie"),
      e: () => store.dispatch("elec/toggleUtilBus"),
      r: () => store.dispatch("elec/toggleLGenCtrl"),
      t: () => store.dispatch("elec/toggleRGenCtrl"),
      a: () => store.dispatch("elec/toggleApuGen"),
      s: () => store.dispatch("elec/toggleLBackupGen"),
      d: () => store.dispatch("elec/toggleRBackupGen"),
      f: () => store.dispatch("elec/toggleSecExtPwr"),
      g: () => store.dispatch("elec/togglePrtExtPwr"),
    };

    // 如果按键有对应的动作，则执行
    if (keyActions[key]) {
      keyActions[key]();
    }
  }
};

const p0 = 100;
const p1 = 140;
const p2 = 180;
const p3 = 454;
const p4 = 494;
const p5 = 534;
const height = 80;

const drawCanvas = () => {
  const canvas = canvasRef.value;
  if (canvas.getContext) {
    /**
     * 供电优先级
     * 有以下电源：ApuGen、lBackupGen、rBackupGen、secExtPwr、prtExtPwr、lGenCtrl、rGenCtrl
     */
    const ctx = canvas.getContext("2d");
    // Get all getters from elec store and store in constants
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    // 清除画布的所有内容
    //画BUSTIE
    drawApu(ctx);
    drawSecExtPower(ctx);
    drawExtPwr(ctx);
    drawXfr(ctx);
    drawGen(ctx);
    drawBackUpGen(ctx);
  }
};

const drawApu = (ctx) => {
  let active = false;
  if (
    (!lGenCtrlState.value && !rGenCtrlState.value) ||
    (lGenCtrlState.value && !lBusTieState.value) ||
    ((rGenCtrlState.value || prtExtPwrState.value) && !rBusTieState.value)
  ) {
    if (!secExtPwrState.value) {
      active = true;
    }
  }
  ctx.beginPath();
  ctx.moveTo((p2 + p3) / 2, height - 15);
  ctx.lineTo((p2 + p3) / 2, height);
  ctx.lineWidth = apuGenState.value && active ? 10 : 2;
  ctx.strokeStyle = apuGenState.value && active ? "rgb(8,255,66)" : "white";
  ctx.stroke();
  ctx.closePath();
};

const drawBackUpGen = (ctx) => {
  ctx.beginPath();
  ctx.moveTo(p1 + 110, height + 222);
  ctx.lineTo(p1 + 110, height + 250);
  ctx.lineWidth = 2;
  ctx.strokeStyle = "white";
  ctx.stroke();
  ctx.closePath();
  ctx.beginPath();
  ctx.moveTo(p4 - 116, height + 222);
  ctx.lineTo(p4 - 116, height + 250);
  ctx.lineWidth = 2;
  ctx.strokeStyle = "white ";
  ctx.stroke();
  ctx.closePath();
  ctx.beginPath();
  ctx.moveTo(p1 + 80, height + 250);
  ctx.lineTo(p4 - 86, height + 250);
  ctx.lineWidth = 2;
  ctx.strokeStyle = "white";
  ctx.stroke();
  ctx.closePath();
  ctx.beginPath();
  ctx.arc(p1 + 80, height + 254, 4, Math.PI * 1, Math.PI * 1.5, false);
  ctx.lineWidth = 2;
  ctx.strokeStyle = "white";
  ctx.stroke();
  ctx.closePath();
  ctx.beginPath();
  ctx.arc(p4 - 86, height + 254, 4, Math.PI * 0, Math.PI * 1.5, true);
  ctx.lineWidth = 2;
  ctx.strokeStyle = "white";
  ctx.stroke();
  ctx.closePath();
  ctx.beginPath();
  ctx.moveTo(p1 + 76, height + 254);
  ctx.lineTo(p1 + 76, height + 284);
  ctx.lineWidth = 2;
  ctx.strokeStyle = "white";
  ctx.stroke();
  ctx.closePath();
  ctx.beginPath();
  ctx.moveTo(p4 - 82, height + 254);
  ctx.lineTo(p4 - 82, height + 284);
  ctx.lineWidth = 2;
  ctx.strokeStyle = "white";
  ctx.stroke();
  ctx.closePath();
};

const drawGen = (ctx) => {
  const lGen = store.getters["elec/lGenCtrl"];
  const rGen = store.getters["elec/rGenCtrl"];
  ctx.beginPath();
  ctx.moveTo(p0 - 30, height + 145);
  ctx.lineTo(p0 - 30, height + 270);
  ctx.lineWidth = lGen ? 10 : 2;
  ctx.strokeStyle = lGen ? "rgb(8,255,66)" : "rgb(255,255,255)";
  ctx.stroke();
  ctx.closePath();
  ctx.beginPath();
  ctx.moveTo(p5 + 25, height + 145);
  ctx.lineTo(p5 + 25, height + 270);
  if (!prtExtPwrState.value) {
    ctx.lineWidth = rGen ? 10 : 2;
    ctx.strokeStyle = rGen ? "rgb(8,255,66)" : "rgb(255,255,255)";
  } else {
    ctx.lineWidth = 2;
    ctx.strokeStyle = "rgb(255,255,255)";
  }
  ctx.stroke();
  ctx.closePath();
};

// Move these computed properties outside drawCanvas so they're accessible everywhere
const lBusTieState = computed(() => store.getters["elec/lBusTie"]);
const rBusTieState = computed(() => store.getters["elec/rBusTie"]);
const utilBusState = computed(() => store.getters["elec/utilBus"]);
const lGenCtrlState = computed(() => store.getters["elec/lGenCtrl"]);
const rGenCtrlState = computed(() => store.getters["elec/rGenCtrl"]);
const apuGenState = computed(() => store.getters["elec/ApuGen"]);
const lBackupGenState = computed(() => store.getters["elec/lBackupGen"]);
const rBackupGenState = computed(() => store.getters["elec/rBackupGen"]);
const secExtPwrState = computed(() => store.getters["elec/secExtPwr"]);
const prtExtPwrState = computed(() => store.getters["elec/prtExtPwr"]);

const drawXfr = (ctx) => {
  //到L XFR 汇流条
  const isActiveL =
    lGenCtrlState.value ||
    (lBusTieState.value && (apuGenState.value || secExtPwrState.value)) ||
    (lBusTieState.value &&
      rBusTieState.value &&
      (prtExtPwrState.value || rGenCtrlState.value));
  lXfrStyle.border = isActiveL
    ? "3px solid rgb(8, 255, 66)"
    : "3px solid rgb(255, 255, 255)";
  lXfrStyle.color = isActiveL ? "rgb(8, 255, 66)" : "rgb(255, 255, 255)";
  lMainBus.border = isActiveL
    ? "3px solid rgb(8, 255, 66)"
    : "3px solid rgb(255, 255, 255)";
  lMainBus.color = isActiveL ? "rgb(8, 255, 66)" : "rgb(255, 255, 255)";
  ctx.beginPath();
  ctx.moveTo(p1 + 3, height + 132);
  ctx.lineTo(isActiveL ? p1 + 91 : p1 + 95, height + 132);
  ctx.lineWidth = isActiveL ? 10 : 2;
  ctx.strokeStyle = isActiveL ? "rgb(8,255,66)" : "white";
  ctx.stroke();
  ctx.closePath();
  ctx.beginPath();
  ctx.arc(
    isActiveL ? p1 + 91 : p1 + 95,
    isActiveL ? height + 137 : height + 133,
    isActiveL ? 10 : 2,
    PI * 1,
    0,
    false
  );
  ctx.fillStyle = isActiveL ? "rgb(8,255,66)" : "white";
  ctx.fill();
  ctx.closePath();
  ctx.beginPath();
  ctx.moveTo(p1 + 96, isActiveL ? height + 137 : height + 133);
  ctx.lineTo(p1 + 96, height + 197);
  ctx.lineWidth = isActiveL ? 10 : 2;
  ctx.strokeStyle = isActiveL ? "rgb(8,255,66)" : "white";
  ctx.stroke();
  ctx.closePath();

  //到 R XFR 汇流条
  const isActiveR =
    rGenCtrlState.value ||
    prtExtPwrState.value ||
    (rBusTieState.value && (apuGenState.value || secExtPwrState.value)) ||
    (lBusTieState.value && rBusTieState.value && lGenCtrlState.value);
  rXfrStyle.border = isActiveR
    ? "3px solid rgb(8, 255, 66)"
    : "3px solid rgb(255, 255, 255)";
  rXfrStyle.color = isActiveR ? "rgb(8, 255, 66)" : "rgb(255, 255, 255)";
  rMainBus.border = isActiveR
    ? "3px solid rgb(8, 255, 66)"
    : "3px solid rgb(255, 255, 255)";
  rMainBus.color = isActiveR ? "rgb(8, 255, 66)" : "rgb(255, 255, 255)";
  ctx.beginPath();
  ctx.moveTo(p4 - 15, height + 132);
  ctx.lineTo(isActiveR ? p4 - 103 : p4 - 107, height + 132);
  ctx.lineWidth = isActiveR ? 10 : 2;
  ctx.strokeStyle = isActiveR ? "rgb(8,255,66)" : "white";
  ctx.stroke();
  ctx.closePath();
  ctx.beginPath();
  ctx.arc(
    isActiveR ? p4 - 103 : p4 - 107,
    isActiveR ? height + 137 : height + 133,
    isActiveR ? 10 : 2,
    PI * 1,
    0,
    false
  );
  ctx.fillStyle = isActiveR ? "rgb(8,255,66)" : "white";
  ctx.fill();
  ctx.closePath();
  ctx.beginPath();
  ctx.moveTo(p4 - 108, isActiveR ? height + 137 : height + 133);
  ctx.lineTo(p4 - 108, height + 197);
  ctx.lineWidth = isActiveR ? 10 : 2;
  ctx.strokeStyle = isActiveR ? "rgb(8,255,66)" : "white";
  ctx.stroke();
  ctx.closePath();
  drawUtilLoadShed(ctx, isActiveL, isActiveR);
  drawBusTie(ctx, isActiveL, isActiveR);
};

const drawUtilLoadShed = (ctx, isActiveL, isActiveR) => {
  const utilBus = store.getters["elec/utilBus"];
  //l util load shed
  ctx.beginPath();
  ctx.moveTo(p0 - 16, height + 144);
  ctx.lineTo(p0 - 16, height + 158);
  ctx.lineWidth = 2;
  ctx.strokeStyle = utilBus && isActiveL ? "rgb(8,255,66)" : "white";
  ctx.stroke();
  ctx.closePath();
  ctx.beginPath();
  ctx.arc(p0 - 12, height + 158, 4, PI * 1, PI * 0.5, true);
  ctx.lineWidth = 2;
  ctx.strokeStyle = utilBus && isActiveL ? "rgb(8,255,66)" : "white";
  ctx.stroke();
  ctx.closePath();
  ctx.beginPath();
  ctx.moveTo(p0 - 12, height + 162);
  ctx.lineTo(p0 - 2, height + 162);
  ctx.lineWidth = 2;
  ctx.strokeStyle = utilBus && isActiveL ? "rgb(8,255,66)" : "white";
  ctx.stroke();
  ctx.closePath();
  // r util load shed
  ctx.beginPath();
  ctx.moveTo(p5 + 12, height + 144);
  ctx.lineTo(p5 + 12, height + 158);
  ctx.lineWidth = 2;
  ctx.strokeStyle = utilBus && isActiveR ? "rgb(8,255,66)" : "white";
  ctx.stroke();
  ctx.closePath();
  ctx.beginPath();
  ctx.arc(p5 + 8, height + 158, 4, PI * 0.5, 0, true);
  ctx.lineWidth = 2;
  ctx.strokeStyle = utilBus && isActiveR ? "rgb(8,255,66)" : "white";
  ctx.stroke();
  ctx.closePath();
  ctx.beginPath();
  ctx.moveTo(p5 + 8, height + 162);
  ctx.lineTo(p5 - 2, height + 162);
  ctx.lineWidth = 2;
  ctx.strokeStyle = utilBus && isActiveR ? "rgb(8,255,66)" : "white";
  ctx.stroke();
  ctx.closePath();
};

const drawExtPwr = (ctx) => {
  ctx.beginPath();
  ctx.moveTo(p3 - 40, height + 60);
  ctx.lineTo(p3 + 60, height + 60);
  ctx.lineWidth = prtExtPwrState.value ? 10 : 2;
  ctx.strokeStyle = prtExtPwrState.value ? "rgb(8,255,66)" : "white";
  ctx.stroke();
  ctx.closePath();
  ctx.beginPath();
  ctx.arc(p3 + 60, height + 64, 4, PI * 1.5, 0, false);
  ctx.lineWidth = prtExtPwrState.value ? 10 : 2;
  ctx.strokeStyle = prtExtPwrState.value ? "rgb(8,255,66)" : "white";
  ctx.stroke();
  ctx.closePath();
  ctx.beginPath();
  ctx.moveTo(p3 + 64, height + 64);
  ctx.lineTo(p3 + 64, height + 120);
  ctx.lineWidth = prtExtPwrState.value ? 10 : 2;
  ctx.strokeStyle = prtExtPwrState.value ? "rgb(8,255,66)" : "white";
  ctx.stroke();
  ctx.closePath();
};

const drawBusTie = (ctx, isActiveL, isActiveR) => {
  let activeLbusTie = lBusTieState.value;
  let activeRbusTie = rBusTieState.value;

  if (lBusTieState.value && rBusTieState.value) {
    //由于无法并联供电，当左右bus tie都打开时，要考虑如下情况
    /**
     * 1.如果左发电机供电，右发电机或者PRT EXT PWR也供电，则两个bustie 断开此时分别供电
     * 2.如果左发电机供电，右发电机和RT EXT PWR都不供电，但是APU或者SEC EXT PWR供电，则L BUS TIE断开，R BUS TIE闭合
     */
    if (lGenCtrlState.value && (rGenCtrlState.value || prtExtPwrState.value)) {
      activeLbusTie = false;
      activeRbusTie = false;
    } else if (secExtPwrState.value && prtExtPwrState.value) {
      activeLbusTie = true;
      activeRbusTie = false;
    }
  } else {
    /**
     * 如果左右bus tie有一个打开了，则要考虑如下情况
     * 1.如果l bus tie 闭合，此时如果左发电机供电，APU或者SEC EXT PWR供电，则L BUS TIE断开
     * 2.如果r bus tie 闭合，此时如果右发动机或 prt ext pwr供电，且APU或者SEC EXT PWR供电则R BUS TIE断开
     */
    if (lBusTieState.value) {
      if (lGenCtrlState.value && (apuGenState.value || secExtPwrState.value)) {
        activeLbusTie = false;
      }
    }
    if (rBusTieState.value) {
      if (
        (rGenCtrlState.value || prtExtPwrState.value) &&
        (apuGenState.value || secExtPwrState.value)
      ) {
        activeRbusTie = false;
      }
    }
  }

  ctx.beginPath();
  ctx.moveTo(p0, height);
  ctx.lineTo(p1, height);
  ctx.lineWidth = isActiveL ? 10 : 2;
  ctx.strokeStyle = isActiveL ? "rgb(8,255,66)" : "white";
  ctx.stroke();
  ctx.closePath();
  //画连接到L MAIN的线
  ctx.beginPath();
  ctx.arc(p1 - 40, height + 4, 4, PI * 1.5, PI * 1, true);
  ctx.lineWidth = isActiveL ? 10 : 2;
  ctx.strokeStyle = isActiveL ? "rgb(8,255,66)" : "white";
  ctx.stroke();
  ctx.closePath();
  ctx.beginPath();
  ctx.moveTo(p1 - 44, height + 4);
  ctx.lineTo(p1 - 44, height + 120);
  ctx.lineWidth = isActiveL ? 10 : 2;
  ctx.strokeStyle = isActiveL ? "rgb(8,255,66)" : "white";
  ctx.stroke();
  ctx.closePath();

  //画L BUS TIE 到 L MAIN BUS
  const isActiveBusTie =
    apuGenState.value ||
    secExtPwrState.value ||
    (lBusTieState.value && isActiveL) ||
    (rBusTieState.value && isActiveR);
  ctx.beginPath();
  ctx.moveTo(p2, height);
  ctx.lineTo(p3, height);
  ctx.lineWidth = isActiveBusTie ? 10 : 2;
  ctx.strokeStyle = isActiveBusTie ? "rgb(8,255,66)" : "white";
  ctx.stroke();
  ctx.closePath();

  //画连接到R MIAN的线
  ctx.beginPath();
  ctx.moveTo(p4, height);
  ctx.lineTo(p5, height);
  ctx.lineWidth = isActiveR ? 10 : 2;
  ctx.strokeStyle = isActiveR ? "rgb(8,255,66)" : "white";
  ctx.stroke();
  ctx.closePath();
  ctx.beginPath();
  ctx.arc(p4 + 40, height + 4, 4, PI * 2, PI * 1.5, true);
  ctx.lineWidth = isActiveR ? 10 : 2;
  ctx.strokeStyle = isActiveR ? "rgb(8,255,66)" : "white";
  ctx.stroke();
  ctx.closePath();
  ctx.beginPath();
  ctx.moveTo(p4 + 44, height + 4);
  ctx.lineTo(p4 + 44, height + 120);
  ctx.lineWidth = isActiveR ? 10 : 2;
  ctx.strokeStyle = isActiveR ? "rgb(8,255,66)" : "white";
  ctx.stroke();
  ctx.closePath();
  //设置左busTie
  drawLBusTieSwitch(ctx, isActiveBusTie, isActiveL, activeLbusTie);
  drawRBusTieSwitch(ctx, isActiveBusTie, isActiveR, activeRbusTie);
};

/**
 * 画右busTie开关
 * @param ctx
 * @param activeBusTie r bus tie 与 l bus tie 之间是否有电
 * @param activeRbusTie R BUS TIE 右边是否有电
 * @param rBusTie R BUS TIE 开关是否可以闭合
 */
const drawRBusTieSwitch = (ctx, activeBusTie, activeRbusTie, rBusTie) => {
  // 计算开关中心点坐标
  const centerX = (p3 + p4) / 2;

  // 根据不同状态设置颜色
  let active = false;
  let color = "rgb(255,198,41)"; // 默认黄色(未连接)
  if (!rBusTieState.value) {
    color = "white"; // 白色(已连接无电)
    active = false; // 开关断开
  } else {
    if (rBusTie) {
      if (activeBusTie || activeRbusTie) {
        color = "rgb(8,255,55)"; // 绿色(有电)
        active = true;
      }
    }
  }

  // 设置基础样式
  ctx.lineWidth = 2;
  ctx.strokeStyle = color;

  // 绘制开关横线
  ctx.beginPath();
  ctx.moveTo(centerX - 12, active ? height - 8 : height - 12);
  ctx.lineTo(centerX + 12, active ? height - 8 : height - 12);
  ctx.stroke();
  ctx.closePath();

  // 绘制开关竖线上部
  ctx.beginPath();
  ctx.moveTo(centerX, active ? height - 8 : height - 12);
  ctx.lineTo(centerX, active ? height + 1 : height - 3);
  ctx.stroke();
  ctx.closePath();

  // 绘制开关竖线下部
  ctx.beginPath();
  ctx.moveTo(centerX, height + 1);
  ctx.lineTo(centerX, height + 7);
  ctx.stroke();
  ctx.closePath();

  // 绘制左右两侧圆点
  ctx.beginPath();
  ctx.arc(p3 + 5, height, 4, PI * 2, 0, true);
  ctx.stroke();
  ctx.closePath();

  ctx.beginPath();
  ctx.arc(p4 - 5, height, 4, PI * 2, 0, true);
  ctx.stroke();
  ctx.closePath();
};

/**
 * 画左busTie开关
 * @param ctx
 * @param activeBusTie l bus tie 与 r bus tie 之间是否有电
 * @param activeLbusTie L BUS TIE 左边是否有电
 * @param lBusTie L BUS TIE 开关是否可以闭合
 */
const drawLBusTieSwitch = (ctx, activeBusTie, activeLbusTie, lBusTie) => {
  // 计算开关中心点坐标
  const centerX = (p1 + p2) / 2;

  // 设置基础样式
  ctx.lineWidth = 2;
  let active = false;
  // 根据不同状态绘制开关
  let color = "rgb(255,198,41)"; // 默认黄色(未连接)
  if (!lBusTieState.value) {
    color = "white"; // 白色(已连接无电)
    active = false; // 开关断开
  } else {
    if (lBusTie) {
      if (activeLbusTie || activeBusTie) {
        color = "rgb(8,255,55)"; // 绿色(有电)
        active = true; // 开关闭合
      }
    }
  }

  // 绘制开关横线
  ctx.beginPath();
  ctx.moveTo(centerX - 12, active ? height - 8 : height - 12);
  ctx.lineTo(centerX + 12, active ? height - 8 : height - 12);
  ctx.strokeStyle = color;
  ctx.stroke();
  ctx.closePath();

  // 绘制开关竖线上部
  ctx.beginPath();
  ctx.moveTo(centerX, active ? height - 8 : height - 12);
  ctx.lineTo(centerX, active ? height + 1 : height - 3);
  ctx.strokeStyle = color;
  ctx.stroke();
  ctx.closePath();

  // 绘制开关竖线下部
  ctx.beginPath();
  ctx.moveTo(centerX, height + 1);
  ctx.lineTo(centerX, height + 7);
  ctx.strokeStyle = color;
  ctx.stroke();
  ctx.closePath();

  // 绘制左右两侧圆点
  ctx.beginPath();
  ctx.arc(p1 + 5, height, 4, PI * 2, 0, true);
  ctx.strokeStyle = color;
  ctx.stroke();
  ctx.closePath();

  ctx.beginPath();
  ctx.arc(p2 - 5, height, 4, PI * 2, 0, true);
  ctx.strokeStyle = color;
  ctx.stroke();
  ctx.closePath();
};

const drawSecExtPower = (ctx) => {
  let active = false;
  if (
    (!lGenCtrlState.value && !rGenCtrlState.value) ||
    (lGenCtrlState.value && !lBusTieState.value) ||
    ((rGenCtrlState.value || prtExtPwrState.value) && !rBusTieState.value)
  ) {
    active = true;
  }
  //画连接到SEC EXT PWR的线
  ctx.beginPath();
  ctx.moveTo((p2 + p3) / 2, height);
  ctx.lineTo((p2 + p3) / 2, height + 60);
  ctx.lineWidth = secExtPwrState.value && active ? 10 : 2;
  ctx.strokeStyle = secExtPwrState.value && active ? "rgb(8,255,66)" : "white";
  ctx.stroke();
  ctx.closePath();
  ctx.beginPath();
  ctx.arc((p2 + p3) / 2 - 4, height + 60, 4, PI * 0.5, 0, true);
  ctx.lineWidth = secExtPwrState.value && active ? 10 : 2;
  ctx.strokeStyle = secExtPwrState.value && active ? "rgb(8,255,66)" : "white";
  ctx.stroke();
  ctx.closePath();
  ctx.beginPath();
  ctx.moveTo((p2 + p3) / 2 - 4, height + 64);
  ctx.lineTo((p2 + p3) / 2 - 70, height + 64);
  ctx.lineWidth = secExtPwrState.value && active ? 10 : 2;
  ctx.strokeStyle = secExtPwrState.value && active ? "rgb(8,255,66)" : "white";
  ctx.stroke();
  ctx.closePath();
};
</script>

<style scoped>
/* Canvas的定位和样式 */
canvas {
  position: absolute;
  top: 0;
  left: 0;
}

.container {
  height: 591px;
  width: 634px;
  position: relative;
  z-index: 10;
}

.apu {
  position: relative;
  height: 40px;
  width: 40px;
  border-radius: 2px;
}

.drive {
  position: relative;
  height: 40px;
  width: 50px;
  border-radius: 2px;
}

.sec_ext_pwr {
  position: relative;
  top: 85px;
  left: 198px;
  height: 40px;
  width: 50px;
  border-radius: 2px;
}

.prt_ext_pwr {
  position: relative;
  top: -58px;
  left: 364px;
  height: 40px;
  width: 50px;
  border-radius: 2px;
}

.bus {
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
  border-radius: 25px;
  width: 100px;
  font-weight: 600;
  height: 25px;
}

.plainFont {
  position: relative;
  font-weight: 600;
}

.disc_font {
  position: relative;
  color: rgb(8, 214, 255);
  font-weight: 600;
}
.white_font {
  position: relative;
  color: rgb(255, 255, 255);
  font-weight: 600;
  font-size: 18px;
}
</style>
